﻿using DevExpress.XtraGrid.Views.BandedGrid;
using DevExpress.XtraGrid.Views.Grid;
using DevExpress.XtraGrid.Views.Tile;
using DevExpress.XtraTreeList;
using DiaoPaiDaYin;
using DXApplicationTangche.Utils;
using System;
using System.Collections.Generic;
using System.Data;
using System.Data.OleDb;
using System.Drawing;
using System.Drawing.Imaging;
using System.IO;
using System.Linq;
using System.Net;
using System.Text;
using System.Text.RegularExpressions;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.Windows.Media;
using System.Windows.Media.Imaging;

namespace DevExpress.XtraGrid.Demos.util
{
    public class FunctionHelper
    {

        private static DateTime? _systemTime = null;

        public static DateTime SystemTime
        {
            get { return _systemTime.HasValue ? _systemTime.Value : DateTime.Now; }
            set { _systemTime = value; }
        }

        public string Uuid { get => uuid; set => uuid = value; }

        #region 日期操作

        /// <summary>
        /// 取得某月的第一天
        /// </summary>
        /// <param name="datetime">要取得月份第一天的时间</param>
        /// <returns></returns>
        public static DateTime FirstDayOfMonth(DateTime datetime)
        {
            return datetime.AddDays(1 - datetime.Day);
        }

        /// <summary>
        /// 取得某月的最后一天
        /// </summary>
        /// <param name="datetime">要取得月份最后一天的时间</param>
        /// <returns></returns>
        public static DateTime LastDayOfMonth(DateTime datetime)
        {
            return datetime.AddDays(1 - datetime.Day).AddMonths(1).AddDays(-1);
        }

        /// <summary>
        /// 取得上个月第一天
        /// </summary>
        /// <param name="datetime">要取得上个月第一天的当前时间</param>
        /// <returns></returns>
        public static DateTime FirstDayOfPreviousMonth(DateTime datetime)
        {
            return datetime.AddDays(1 - datetime.Day).AddMonths(-1);
        }

        /// <summary>
        /// 取得上个月的最后一天
        /// </summary>
        /// <param name="datetime">要取得上个月最后一天的当前时间</param>
        /// <returns></returns>
        public static DateTime LastDayOfPrdviousMonth(DateTime datetime)
        {
            return datetime.AddDays(1 - datetime.Day).AddDays(-1);
        }

        public static DateTime FirstDateOfQuarter(DateTime datetime)
        {
            return datetime.AddMonths(0 - (datetime.Month - 1) % 3).AddDays(1 - datetime.Day);
        }

        public static DateTime LastDateOfQuarter(DateTime datetime)
        {
            return FirstDateOfQuarter(datetime).AddMonths(3).AddDays(-1);
        }

        public static DateTime FirstDayOfLastQuarter(DateTime datetime)
        {
            return DateTime.Parse(datetime.AddMonths(-3 - ((datetime.Month - 1) % 3)).ToString("yyyy/MM/01"));
        }

        public static DateTime LastDayOfLastQuarter(DateTime datetime)
        {
            return DateTime.Parse(SystemTime.AddMonths(0 - ((SystemTime.Month - 1) % 3)).ToString("yyyy-MM-01")).AddDays(-1);
        }

        /// <summary>
        /// 获取指定周数的开始日期(周一)和结束日期（周末）
        /// </summary>
        /// <param name="year">年份</param>
        /// <param name="index">周数</param>
        /// <param name="first">当此方法返回时，则包含参数 year 和 index 指定的周的开始日期的 System.DateTime 值；如果失败，则为 System.DateTime.MinValue。</param>
        /// <param name="last">当此方法返回时，则包含参数 year 和 index 指定的周的结束日期的 System.DateTime 值；如果失败，则为 System.DateTime.MinValue。</param>
        /// <returns></returns>
        public static bool GetDaysOfWeeks(int year, int index, out DateTime first, out DateTime last)
        {
            first = DateTime.MinValue;
            last = DateTime.MinValue;
            if (year < 1700 || year > 9999)
            {
                //"年份超限"
                return false;
            }
            if (index < 1 || index > 53)
            {
                //"周数错误"
                return false;
            }
            DateTime startDay = new DateTime(year, 1, 1);  //该年第一天
            DateTime endDay = new DateTime(year + 1, 1, 1).AddMilliseconds(-1);
            int dayOfWeek = 0;
            if (Convert.ToInt32(startDay.DayOfWeek.ToString("d")) > 0)
                dayOfWeek = Convert.ToInt32(startDay.DayOfWeek.ToString("d"));  //该年第一天为星期几,星期天为7

            if (dayOfWeek == 0) { dayOfWeek = 7; }
            if (index == 1)
            {
                first = startDay;
                if (dayOfWeek == 7)
                {
                    last = first;
                }
                else
                {
                    last = startDay.AddDays((7 - dayOfWeek));
                }
            }
            else
            {
                first = startDay.AddDays((7 - dayOfWeek + 1) + (index - 2) * 7); //index周的起始日期
                last = first.AddDays(6);
                if (last > endDay)
                {
                    last = endDay;
                }
            }
            if (first > endDay)  //startDayOfWeeks不在该年范围内
            {
                //"输入周数大于本年最大周数";
                return false;
            }
            return true;
        }

        //计算周一至周日的周数
        //public static int GetWeekOfYear(DateTime dt)
        //{
        //    GregorianCalendar gc = new GregorianCalendar();
        //    int weekOfYear = gc.GetWeekOfYear(dt, CalendarWeekRule.FirstDay, DayOfWeek.Monday);
        //    return weekOfYear;
        //}
        //计算周一至周日的周数
        public static int WeekOfYear1(DateTime dt)
        {
            //找到今年的第一天是周几
            int firstWeekend = Convert.ToInt32(DateTime.Parse(dt.Year + "-1-1").DayOfWeek);

            //获取第一周的差额,如果是周日，则firstWeekend为0，第一周也就是从周天开始的。
            int weekDay = firstWeekend == 0 ? 1 : (7 - firstWeekend + 1);

            //获取今天是一年当中的第几天
            int currentDay = dt.DayOfYear;

            //（今天 减去 第一周周末）/7 等于 距第一周有多少周 再加上第一周的1 就是今天是今年的第几周了
            //    刚好考虑了惟一的特殊情况就是，今天刚好在第一周内，那么距第一周就是0 再加上第一周的1 最后还是1
            int current_week = Convert.ToInt32(Math.Ceiling((currentDay - weekDay) / 7.0)) + 1;
            return current_week;
        }
        #endregion

        #region 取值操作

        public static string GetValue(object o, string def = "")
        {
            if (o != null)
            {
                if (o.ToString().Trim() != "")
                {
                    return o.ToString().Trim();
                }
                else
                {
                    return def;
                }
            }
            else
            {
                return def;
            }
        }

        public static string GetDateTimeValue(object o, string format = "yyyy/MM/dd")
        {
            if (o != null)
            {
                if (o.ToString().Trim() != "")
                {
                    DateTime v = SystemTime;
                    if (DateTime.TryParse(o.ToString().Trim(), out v))
                    {
                        return v.ToString(format);
                    }
                    else
                    {
                        return "";
                    }
                }
                else
                {
                    return "";
                }
            }
            else
            {
                return "";
            }
        }

        public static string GetNumberValue(object o, string def = "")
        {
            if (o != null)
            {
                if (o.ToString().Trim() != "")
                {
                    decimal v = 0;
                    if (decimal.TryParse(o.ToString().Trim(), out v))
                    {
                        return v.ToString().Trim();
                    }
                    else
                    {
                        return def;
                    }
                }
                else
                {
                    return def;
                }
            }
            else
            {
                return def;
            }
        }

        public static string GetBooleanValue(object o, string def = "")
        {
            if (o != null)
            {
                if (o.ToString().Trim() != "")
                {
                    bool v = false;
                    if (bool.TryParse(o.ToString().Trim(), out v))
                    {
                        return v.ToString().Trim();
                    }
                    else
                    {
                        return def;
                    }
                }
                else
                {
                    return def;
                }
            }
            else
            {
                return def;
            }
        }
        #endregion

        #region 单号
        internal static string GetgridViewValue(TreeList treeList一览, object focusedRowHandle, string v)
        {
            throw new NotImplementedException();
        }

        /// <summary>
        /// 取单号
        /// </summary>
        /// <param name="tableName">表名</param>
        /// <param name="billNoField">单号字段</param>
        /// <param name="formatStr">格式化后缀字段</param>
        /// <param name="prefix">前缀</param>
        /// <returns></returns>
        //public static String generateBillNo_坚山(String tableName, String billNoField, String prefix, String formatStr)
        //{
        //    String sql = "select right(max(" + billNoField + ")," + formatStr.Length + ")+1  as code from " + tableName + " "
        //        + " where left(" + billNoField + ", " + prefix.Length + ") = '" + prefix + "'";
        //    DataTable dataTable = SQLmtm.GetDataTable(sql);
        //    if (dataTable.Rows.Count == 0)
        //    {
        //        sql = "select CONCAT('" + prefix + "', '" + string.Format("{0:" + formatStr + "}", 1) + "') as code";
        //        return SQLmtm.GetDataTable(sql).Rows[0]["code"].ToString();
        //    }
        //    else if (String.IsNullOrEmpty(dataTable.Rows[0]["code"].ToString()))
        //    {
        //        sql = "select CONCAT('" + prefix + "' , '" + string.Format("{0:" + formatStr + "}", 1) + "') as code";
        //        return SQLmtm.GetDataTable(sql).Rows[0]["code"].ToString();
        //    }
        //    else
        //    {
        //        String suffix = string.Format("{0:" + formatStr + "}", Convert.ToInt32(dataTable.Rows[0]["code"].ToString()));
        //        sql = "select CONCAT('" + prefix + "', '" + suffix + "') as code";
        //        return SQLmtm.GetDataTable(sql).Rows[0]["code"].ToString();
        //    }
        //}
        #endregion

        #region json序列化
        public static String JsonSerialization(object ob)
        {
            String str = Newtonsoft.Json.JsonConvert.SerializeObject(ob);
            return str;
        }
        #endregion

        #region json反序列化
        public static T JsonDeserialization<T>(String str)
        {
            return Newtonsoft.Json.JsonConvert.DeserializeObject<T>(str);
        }
        #endregion

        #region 字符串格式
        /// <summary>
        /// 是否是正数
        /// </summary>
        /// <param name="str"></param>
        /// <returns></returns>
        public static bool IsFloat(String str)
        {
            string regextext = @"^[+]{0,1}(\d+)$|^[+]{0,1}(\d+\.\d+)$";
            Regex regex = new Regex(regextext, RegexOptions.None);
            return regex.IsMatch(str);
        }
        /// <summary>
        /// 是否是半角
        /// </summary>
        /// <param name="str"></param>
        /// <returns></returns>
        public static bool Is半角(String str)
        {
            if (str.Length == Encoding.Default.GetByteCount(str))
            {
                return true;
            }
            else
            {
                return false;
            }
        }
        /// <summary>
        /// 正数不包含0
        /// </summary>
        /// <param name="str"></param>
        /// <returns></returns>
        public static bool Is大于0(String str)
        {
            string regextext = @"^([1-9]\d*(\.\d*[1-9])?)|(0\.\d*[1-9])$";
            Regex regex = new Regex(regextext, RegexOptions.None);
            return regex.IsMatch(str);
        }

        /// <summary>
        /// 正整数包含0
        /// </summary>
        /// <returns></returns>
        public static bool Is正整数(String str)
        {
            String regextext = @"^([1-9]\d*|[0]{1,1})$";
            Regex regex = new Regex(regextext, RegexOptions.None);
            return regex.IsMatch(str);
        }
        #endregion

        private string uuid = System.Guid.NewGuid().ToString("N");

        /// <summary>
        /// 读Excel转datatable
        /// </summary>
        /// <param name="hasTitle">第一行算不算表头</param>
        /// <returns></returns>
        public static DataTable GetDataFromExcelByConn(String sheetName, bool hasTitle = false)
        {
            OpenFileDialog openFile = new OpenFileDialog();
            //openFile.Filter = "Excel(*.xlsx)|*.xlsx|Excel(*.xls)|*.xls";
            openFile.Filter = MIMEConst.EXCEL_MIME;
            openFile.InitialDirectory = Environment.GetFolderPath(Environment.SpecialFolder.Desktop);
            openFile.Multiselect = false;
            if (openFile.ShowDialog() == DialogResult.Cancel) return null;
            var filePath = openFile.FileName;
            string fileType = System.IO.Path.GetExtension(filePath);
            if (string.IsNullOrEmpty(fileType)) return null;

            using (DataSet ds = new DataSet())
            {
                string strCon = string.Format("Provider=Microsoft.Jet.OLEDB.{0}.0;" +
                                "Extended Properties=\"Excel {1}.0;HDR={2};IMEX=1;\";" +
                                "data source={3};",
                                (fileType == ".xls" ? 4 : 12), (fileType == ".xls" ? 8 : 12), (hasTitle ? "Yes" : "NO"), filePath);
                string strCom = " SELECT * FROM ["+ sheetName + "$]";
                using (OleDbConnection myConn = new OleDbConnection(strCon))
                using (OleDbDataAdapter myCommand = new OleDbDataAdapter(strCom, myConn))
                {
                    myConn.Open();
                    myCommand.Fill(ds);
                }
                if (ds == null || ds.Tables.Count <= 0) return null;
                return ds.Tables[0];
            }
        }

        /// <summary>
        /// gridview取数据
        /// </summary>
        /// <param name="gv"></param>
        /// <param name="RowHandle"></param>
        /// <param name="FieldName"></param>
        /// <returns></returns>
        public static String GetgridViewValue(GridView gv, int RowHandle, String FieldName)
        {
            try
            {
                return gv.GetRowCellValue(RowHandle, FieldName).ToString();
            }
            catch
            {
                return "";
            }
        }

        /// <summary>
        /// gridview取数据
        /// </summary>
        /// <param name="gv"></param>
        /// <param name="RowHandle"></param>
        /// <param name="FieldName"></param>
        /// <returns></returns>
        public object GetgridViewValueObject(GridView gv, int RowHandle, String FieldName)
        {
            try
            {
                return gv.GetRowCellValue(RowHandle, FieldName);
            }
            catch
            {
                return null;
            }
        }
        /// <summary>
        /// bandedgridview取数据
        /// </summary>
        /// <param name="gv"></param>
        /// <param name="RowHandle"></param>
        /// <param name="FieldName"></param>
        /// <returns></returns>
        public static String GetbandedgridViewValue(BandedGridView gv, int RowHandle, String FieldName)
        {
            try
            {
                return gv.GetRowCellValue(RowHandle, FieldName).ToString();
            }
            catch
            {
                return "";
            }
        }
        /// <summary>
        /// AdvBandedGridView取数据
        /// </summary>
        /// <param name="gv"></param>
        /// <param name="RowHandle"></param>
        /// <param name="FieldName"></param>
        /// <returns></returns>
        public static String GetAdvBandedgridViewValue(AdvBandedGridView gv, int RowHandle, String FieldName)
        {
            try
            {
                return gv.GetRowCellValue(RowHandle, FieldName).ToString();
            }
            catch
            {
                return "";
            }
        }
        /// <summary>
        /// tileview取数据
        /// </summary>
        /// <param name="gv"></param>
        /// <param name="RowHandle"></param>
        /// <param name="FieldName"></param>
        /// <returns></returns>
        public static String getTileView(TileView tv, int RowHandle, String FieldName)
        {
            try
            {
                return tv.GetRowCellValue(RowHandle, FieldName).ToString();
            }
            catch
            {
                return "";
            }
        }
        /// <summary>
        /// PictureBox旋转
        /// </summary>
        /// <param name="img"></param>
        /// <param name="angle"></param>
        /// <returns></returns>
        public static Image GetRotateImage(Image img, float angle)
        {
            angle = angle % 360;//弧度转换
            double radian = angle * Math.PI / 180.0;
            double cos = Math.Cos(radian);
            double sin = Math.Sin(radian);
            //原图的宽和高
            int w = img.Width;
            int h = img.Height;
            int W = (int)(Math.Max(Math.Abs(w * cos - h * sin), Math.Abs(w * cos + h * sin)));
            int H = (int)(Math.Max(Math.Abs(w * sin - h * cos), Math.Abs(w * sin + h * cos)));
            //目标位图
            Image dsImage = new Bitmap(W, H, img.PixelFormat);
            using (System.Drawing.Graphics g = System.Drawing.Graphics.FromImage(dsImage))
            {
                g.InterpolationMode = System.Drawing.Drawing2D.InterpolationMode.Bilinear;
                g.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.HighQuality;
                //计算偏移量
                Point Offset = new Point((W - w) / 2, (H - h) / 2);
                //构造图像显示区域：让图像的中心与窗口的中心点一致
                Rectangle rect = new Rectangle(Offset.X, Offset.Y, w, h);
                Point center = new Point(rect.X + rect.Width / 2, rect.Y + rect.Height / 2);
                g.TranslateTransform(center.X, center.Y);
                g.RotateTransform(360 - angle);
                //恢复图像在水平和垂直方向的平移
                g.TranslateTransform(-center.X, -center.Y);
                g.DrawImage(img, rect);
                //重至绘图的所有变换
                g.ResetTransform();
                g.Save();
            }
            return dsImage;
        }

        public static Image getSSHIRT()
        {
            return DXApplicationTangche.Properties.Resources.SSHIRT;
        }
        /// <summary>
        /// 通过URLImage
        /// </summary>
        /// <param name="url"></param>
        /// <returns></returns>
        public static Image getImageByURL(String url)
        {
            try
            {
                Random seed = new Random();
                WebRequest webreq = WebRequest.Create(url);
                WebResponse webres = webreq.GetResponse();
                Stream stream = webres.GetResponseStream();
                Image image = Image.FromStream(stream);
                stream.Close();
                return image;
            }
            catch (Exception ex)
            {
                System.Diagnostics.Debug.WriteLine("====================通过URL取图片失败=======================\n" + ex.Message);
                return getSSHIRT();
            }
        }
        /// <summary>
        /// 判断远程文件是否存在
        /// </summary>
        /// <param name="fileUrl"></param>
        /// <returns></returns>
        public static Boolean RemoteFileExists(string fileUrl)
        {
            HttpWebRequest re = null;
            HttpWebResponse res = null;
            try
            {
                re = (HttpWebRequest)WebRequest.Create(fileUrl);
                res = (HttpWebResponse)re.GetResponse();
                if (res.ContentLength != 0)
                {
                    //MessageBox.Show("文件存在");
                    return true;
                }
            }
            catch (Exception)
            {
                //MessageBox.Show("无此文件");
                return false;
            }
            finally
            {
                if (re != null)
                {
                    re.Abort();//销毁关闭连接
                }
                if (res != null)
                {
                    res.Close();//销毁关闭响应
                }
            }
            return false;
        }
        /// <summary>
        /// 判断本地文件是否存在
        /// </summary>
        /// <param name="path"></param>
        /// <returns></returns>
        public static Boolean LocalFileExists(string filePath)
        {
            if (File.Exists(filePath))
            {
                return true;
            }
            else
            {
                return false;
            }
        }
        /// <summary>
        /// 识别urlStr是否是网络路径
        /// </summary>
        /// <param name="urlStr"></param>
        /// <returns></returns>
        public static Boolean UrlDiscern(string urlStr)
        {
            if (Regex.IsMatch(urlStr, @"((http|ftp|https)://)(([a-zA-Z0-9\._-]+\.[a-zA-Z]{2,6})|([0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}))(:[0-9]{1,4})*(/[a-zA-Z0-9\&%_\./-~-]*)?"))
            {
                return true;
            }
            else
            {
                return false;
            }
        }
    }
    /// <summary>
    /// 图片和数据库String的转换
    /// </summary>
    public class ImageFormatChange
    {
        public static string ChangeImageToString(Image image, ImageFormat imageFormat)
        {
            try
            {
                MemoryStream ms = new MemoryStream();
                image.Save(ms, imageFormat);
                byte[] arr = new byte[ms.Length];
                ms.Position = 0;
                ms.Read(arr, 0, (int)ms.Length);
                ms.Close();
                string pic = Convert.ToBase64String(arr);

                return pic;
            }
            catch (Exception)
            {
                return "Fail to change bitmap to string!";
            }
        }

        public static Image ChangeStringToImage(string pic)
        {
            try
            {
                byte[] imageBytes = Convert.FromBase64String(pic);
                //读入MemoryStream对象
                MemoryStream memoryStream = new MemoryStream(imageBytes, 0, imageBytes.Length);
                memoryStream.Write(imageBytes, 0, imageBytes.Length);
                //转成图片
                Image image = Image.FromStream(memoryStream);

                return image;
            }
            catch (Exception)
            {
                Image image = null;
                return image;
            }
        }
    }

}
